package com.example.leetcode.c101_c200.c109;
/**
 * 给定一个单链表，其中的元素按升序排序，将其转换为高度平衡的二叉搜索树。
 *
 * 本题中，一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
 *
 * 示例:
 *
 * 给定的有序链表： [-10, -3, 0, 5, 9],
 *
 * 一个可能的答案是：[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树：
 *
 *       0
 *      / \
 *    -3   9
 *    /   /
 *  -10  5
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */

import com.example.leetcode.common.ListNode;
import com.example.leetcode.common.ListNodeWrapper;
import com.example.leetcode.common.TreeNode;
import com.example.leetcode.common.TreeNodeWrapper;

/**
 * 有序链表转换二叉搜索树
 * @author zhanpengguo
 * @date 2020/10/2 14:29
 */
public class Solution {

    public TreeNode sortedListToBST(ListNode head) {
        // 找出中位数
        // 中位数左边是左子树，右边是右子树，中位数是根节点
        return digui(head, null);
    }

    private TreeNode digui(ListNode left, ListNode right) {
        if (left == right) {
            return null;
        }
        ListNode middle = getMiddle(left, right);
        TreeNode root = new TreeNode(middle.val);
        root.left = digui(left, middle);
        root.right = digui(middle.next, right);
        return root;
    }

    private ListNode getMiddle(ListNode left,ListNode right) {
        ListNode slow = left;
        ListNode fast = left;
        while (fast != right && fast.next != right) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

    public static void main(String[] args) {
        ListNode head = ListNodeWrapper.stringToListNode("[-10, -3, 0, 5, 9]");
        Solution solution = new Solution();
        TreeNode root = solution.sortedListToBST(head);
        TreeNodeWrapper.prettyPrintTree(root);
    }
}
